package edu.olin.scheduler.gui;

import edu.olin.scheduler.common.*;
import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Iterator;

public class GUIPrefs {
    
    //interface for objects that should be notified when any GUIPref is changed
    public interface Listener { public void guiPrefsChanged(); }
    
    //Colors
    private static Color dailyBGColor = new Color(255,255,204); // #ffffcc, the DailyDisplay bg color
    private static Color mtbgColor = new Color(255,255,255); //the BG color for meetings
    private static Color mtbgColorConflict = new Color(255,185,160); //the BG color for meetings that are in conflict
    private static Color mtfgColor = Color.BLACK; //the text and arrow color on meetings
    private static Color horizMajorColor = new Color(255,221,170); // #ffddaa, the major horizontal line color
    private static Color horizMinorColor = new Color(255,238,187); // #ffeebb, the minor horizontal line color
    private static Color marginBGColor = new Color(255,231,170); // the color behind the marginal (day & time) labels
    private static Color marginFGColor = Color.BLACK; // The color in which to draw the marginal (day & time) labels and markings
    
    //Fonts
    private static Font majorTimeFont = new Font("SansSerif",Font.BOLD,16); //the font used to draw the marginal time
    private static Font dayOfWeekFont = new Font("SansSerif",Font.BOLD,16); //the font used to draw the day of the week
    private static Font meetingFont = new Font("SansSerif",Font.PLAIN,12); //the font used to draw the meetings

    //Date/Time Display
    private static boolean showMeetingTimes = false; //do we show times on the meeting themselves?
    private static boolean is24hour = false; //do we use 24-hour time?
    private static boolean weekendVisible = false; //do we show Saturday/Sunday?
    private static SimpleTime start = new SimpleTime(8,00); //earliest time of day to display
    private static SimpleTime end = new SimpleTime(12+6,00); //latest time of day to display
    
    //Margins
    private static int marginSize = 3; //margin in pixels
    private static int headerSize = 30; //height of day-of-week headers
    
    //prefs change listeners
    private static ArrayList<Listener> prefsListeners;
    
    //Register a new Listener
    public static void addListener(Listener el){
        //whenever a GUIPreference is changed, the registered listeners will have their repaint() methods invoked
        if(prefsListeners==null){ prefsListeners = new ArrayList(); }
        prefsListeners.add(el);
        }
    
    //Removes the given Listener from the list of registered listeners
    public static void removeListener(Listener el){
        if(prefsListeners==null){ prefsListeners = new ArrayList(); }
        while(prefsListeners.remove(el)){} //remove every instance encountered
        }
    
    //Notifies all of the listeners that a preference has changed
    private static void notifyListeners(){
        if(prefsListeners==null){ prefsListeners = new ArrayList(); return; }
        Iterator<Listener> itr = prefsListeners.iterator();
        while(itr.hasNext()){
            Listener el = itr.next();
            if(el!=null){ el.guiPrefsChanged(); }
            }
        }

    //Accessor Methods
    
    public static SimpleTime getStart(){ return start; }
    public static void setStart(SimpleTime aStart){
        if(aStart==null){ throw new IllegalArgumentException("Cannot have a null start time"); }
        if(!aStart.isBefore(end)){ throw new IllegalArgumentException("Start time must be before end time"); }
        start = aStart;
        notifyListeners();
        }
    
    public static SimpleTime getEnd(){ return end; }
    public static void setEnd(SimpleTime aEnd){
        if(aEnd==null){ throw new IllegalArgumentException("Cannot have a null start time"); }
        if(!aEnd.isAfter(start)){ throw new IllegalArgumentException("Start time must be before end time"); }
        end = aEnd;
        notifyListeners();
        }

    public static int getMarginSize(){ return marginSize; }
    public static void setMarginSize(int aMarginSize){ marginSize = aMarginSize; notifyListeners(); }
    
    public static int getHeaderSize(){ return headerSize; }
    public static void setHeaderSize(int aHeaderSize){ headerSize = aHeaderSize; notifyListeners(); }
    
    public static boolean is24hour(){ return is24hour; }
    public static void set24hour(boolean aIs24hour){ is24hour = aIs24hour; notifyListeners(); }
    
    public static boolean isWeekendVisible(){ return weekendVisible; }
    public static void setWeekendVisible(boolean aWeekendVisible){ weekendVisible = aWeekendVisible; notifyListeners(); }
    
    public static boolean getShowMeetingTimes(){ return showMeetingTimes; }
    public static void setShowMeetingTimes(boolean aShowMeetingTimes){ showMeetingTimes = aShowMeetingTimes; notifyListeners(); }

    public static Color getDailyBGColor(){ return dailyBGColor; }
    public static void  setDailyBGColor(Color aDailyBGColor){ dailyBGColor = aDailyBGColor; notifyListeners(); }
    
    public static Color getMtbgColor(){ return mtbgColor; }
    public static void  setMtbgColor(Color aMtbgColor){ mtbgColor = aMtbgColor; notifyListeners(); }
    
    public static Color getMtbgColorConflict(){ return mtbgColorConflict; }
    public static void  setMtbgColorConflict(Color aMtbgColorConflict){ mtbgColorConflict = aMtbgColorConflict; notifyListeners(); }
    
    public static Color getMtfgColor(){ return mtfgColor; }
    public static void  setMtfgColor(Color aMtfgColor){ mtfgColor = aMtfgColor; notifyListeners(); }
    
    public static Color getHorizMajorColor(){ return horizMajorColor; }
    public static void  setHorizMajorColor(Color aHorizMajorColor){ horizMajorColor = aHorizMajorColor; notifyListeners(); }
    
    public static Color getHorizMinorColor(){ return horizMinorColor; }
    public static void  setHorizMinorColor(Color aHorizMinorColor){ horizMinorColor = aHorizMinorColor; notifyListeners(); }
    
    public static Color getMarginBGColor(){ return marginBGColor; }
    public static void  setMarginBGColor(Color aMarginBGColor){ marginBGColor = aMarginBGColor; notifyListeners(); }
    
    public static Color getMarginFGColor(){ return marginFGColor; }
    public static void  setMarginFGColor(Color aMarginFGColor){ marginFGColor = aMarginFGColor; notifyListeners(); }
    
    public static Font  getMajorTimeFont(){ return majorTimeFont; }
    public static void  setMajorTimeFont(Font aMajorTimeFont){ majorTimeFont = aMajorTimeFont; notifyListeners(); }
    
    public static Font  getDayOfWeekFont(){ return dayOfWeekFont; }
    public static void  setDayOfWeekFont(Font aDayOfWeekFont){ dayOfWeekFont = aDayOfWeekFont; notifyListeners(); }
    
    public static Font  getMeetingFont(){ return meetingFont; }
    public static void  setMeetingFont(Font aMeetingFont){ meetingFont = aMeetingFont; notifyListeners(); }

    }
